package com.heu.blood.send.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heu.blood.application.dictenum.ApplicationStateEnum;
import com.heu.blood.application.entity.BloodApplicationEntity;
import com.heu.blood.application.entity.BloodApplicationItemEntity;
import com.heu.blood.application.service.BloodApplicationItemService;
import com.heu.blood.application.service.BloodApplicationService;
import com.heu.blood.charge.dictenum.BloodChargeTypeEnum;
import com.heu.blood.charge.dictenum.PaymentProjectEnum;
import com.heu.blood.charge.entity.BloodChargeEntity;
import com.heu.blood.charge.service.BloodChargeService;
import com.heu.blood.common.Constant.ConstantData;
import com.heu.blood.common.enums.BloodChargeEnum;
import com.heu.blood.common.utils.GenerateNumberBySnowFlake;
import com.heu.blood.common.utils.PageUtils;
import com.heu.blood.common.utils.Query;
import com.heu.blood.match.dictenum.BloodStateEnum;
import com.heu.blood.match.entity.BloodInformationEntity;
import com.heu.blood.match.service.BloodInformationService;
import com.heu.blood.send.dao.BloodSendDao;
import com.heu.blood.send.entity.BloodSendEntity;
import com.heu.blood.send.service.BloodSendService;
import com.heu.blood.send.vo.BloodSendVo;
import com.heu.blood.send.vo.BloodSendWithPatientVo;
import com.heu.blood.storge.dictenum.OutStorageReasonEnum;
import com.heu.blood.storge.entity.BloodInStorgeEntity;
import com.heu.blood.storge.entity.BloodOutStorgeEntity;
import com.heu.blood.storge.service.BloodInStorgeService;
import com.heu.blood.storge.service.BloodOutStorgeService;
import com.heu.blood.storge.service.impl.BloodOutStorgeServiceImpl;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;


@Service("bloodSendService")
public class BloodSendServiceImpl extends ServiceImpl<BloodSendDao, BloodSendEntity> implements BloodSendService {

    @Autowired
    BloodInformationService bloodInformationService;

    @Autowired
    BloodApplicationService bloodApplicationService;

    @Autowired
    BloodSendDao bloodSendDao;

    @Autowired
    BloodApplicationItemService bloodApplicationItemService;

    @Autowired
    BloodOutStorgeServiceImpl bloodOutStorgeService;

    @Autowired
    BloodChargeService bloodChargeService;

    @Autowired
    BloodInStorgeService bloodInStorgeService;

    @Autowired
    BloodOutStorgeService outBloodOutStorgeService;



    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<BloodSendEntity> page = this.page(
                new Query<BloodSendEntity>().getPage(params),
                new QueryWrapper<BloodSendEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    @Transactional
    public int sendBlood(BloodSendVo bloodSend) {
        // 1.先设置一下操作的时间，并把该发血数据进行保存
        bloodSend.setOperatorTime(new Date());
        this.save(bloodSend);
        // 2.更新一下血液信息表里面的血液状态,将其更新为已发血
        LambdaUpdateWrapper<BloodInformationEntity> bloodInfoUpdateWrapper = new LambdaUpdateWrapper<>();
        bloodInfoUpdateWrapper.set(BloodInformationEntity::getBloodState, BloodStateEnum.BLOOD_ALREADY_SEND.code());
        bloodInfoUpdateWrapper.eq(BloodInformationEntity::getBloodId,bloodSend.getBloodId());
        bloodInformationService.update(bloodInfoUpdateWrapper);
        // 3.更新一下申请单状态
        LambdaUpdateWrapper<BloodApplicationEntity> bloodApplicationLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        bloodApplicationLambdaUpdateWrapper.set(BloodApplicationEntity::getApplicationState, ApplicationStateEnum.SEND_GET_BLOOD.code());
        bloodApplicationLambdaUpdateWrapper.eq(BloodApplicationEntity::getApplicationId,bloodSend.getApplicationId());
        bloodApplicationService.update(bloodApplicationLambdaUpdateWrapper);
        // 4.更新一下申请项里面的已发血液量
        LambdaUpdateWrapper<BloodApplicationItemEntity> bloodApplicationItemEntityUpdateWrapper = new LambdaUpdateWrapper<>();
        bloodApplicationItemEntityUpdateWrapper.setSql("`sent_part_blood` = `sent_part_blood` + " + bloodSend.getBloodCount());
        bloodApplicationItemEntityUpdateWrapper.eq(BloodApplicationItemEntity::getId,bloodSend.getBloodApplicationItemId());
        bloodApplicationItemService.update(bloodApplicationItemEntityUpdateWrapper);
        return 0;
    }

    @Override
    public List<BloodSendVo> selectSendBloodWithId(BloodSendEntity bloodSend) {
        return bloodSendDao.selectSendBloodWithId(bloodSend);
    }

    @Override
    @Transactional
    public int sureGetBlood(BloodSendVo bloodSend) {
        // 创建一个出库的单据号
        GenerateNumberBySnowFlake generateNumberBySnowFlake = new GenerateNumberBySnowFlake(ConstantData.BLOOD_OUT_STORAGE_NO_WORK_ID,ConstantData.BLOOD_OUT_STORAGE_NO_PREFIX );
        String outStorageId = generateNumberBySnowFlake.genNumberByflag();
        // 1.设置完成时间之后，取血人以及取血时间的更新
        bloodSend.setRecipientTime(new Date());
        this.updateById(bloodSend);
        // 2.修改血液状态为已使用，只要是使用了就不可以退回去了
        LambdaUpdateWrapper<BloodInformationEntity> bloodInfoUpdateWrapper = new LambdaUpdateWrapper<>();
        bloodInfoUpdateWrapper.set(BloodInformationEntity::getBloodState, BloodStateEnum.USED.code());
        bloodInfoUpdateWrapper.set(BloodInformationEntity::getBloodBankDeliveryId,outStorageId); // 设置出库编号
        bloodInfoUpdateWrapper.eq(BloodInformationEntity::getBloodId,bloodSend.getBloodId());
        bloodInformationService.update(bloodInfoUpdateWrapper);
        // 新增：同步更新blood_in_storge表的出库编号
        LambdaUpdateWrapper<BloodInStorgeEntity> inStorgeUpdateWrapper = new LambdaUpdateWrapper<>();
        inStorgeUpdateWrapper.set(BloodInStorgeEntity::getBloodBankDeliveryId, outStorageId); // 设置出库编号
        inStorgeUpdateWrapper.eq(BloodInStorgeEntity::getBloodId, bloodSend.getBloodId());
        bloodInStorgeService.update(inStorgeUpdateWrapper);

        LambdaQueryWrapper<BloodInformationEntity> bloodInfoQueryWrapper = new LambdaQueryWrapper<>();
        bloodInfoQueryWrapper.eq(BloodInformationEntity::getBloodId,bloodSend.getBloodId());
        List<BloodInformationEntity> list = bloodInformationService.list(bloodInfoQueryWrapper);
        //修改申请单的状态为输血后评价
        LambdaUpdateWrapper<BloodApplicationEntity> bloodApplicationEntityUpdateWrapper = new LambdaUpdateWrapper<>();
        bloodApplicationEntityUpdateWrapper.set(BloodApplicationEntity::getApplicationState,ApplicationStateEnum. POST_TRANSFUSION_EVALUATION.code());
        bloodApplicationEntityUpdateWrapper.eq(Strings.isNotBlank(bloodSend.getApplicationId()),BloodApplicationEntity::getApplicationId,bloodSend.getApplicationId());
        bloodApplicationService.update(bloodApplicationEntityUpdateWrapper);
        // 3.修改申请单的状态 将发血辆给弄上去
        LambdaUpdateWrapper<BloodApplicationItemEntity> applicationWrapper = new LambdaUpdateWrapper<>();
        applicationWrapper.eq(BloodApplicationItemEntity::getId,bloodSend.getBloodApplicationItemId());
        applicationWrapper.setSql("sent_part_blood = sent_part_blood + " + bloodSend.getBloodCount());
        bloodApplicationItemService.update(applicationWrapper);
        // 4.在出库表里面塞一份
        BloodOutStorgeEntity outStorgeEntity = new BloodOutStorgeEntity();
        BeanUtils.copyProperties(bloodSend,outStorgeEntity); // 拷贝一份数据进来
        outStorgeEntity.setOutStorgeReason(OutStorageReasonEnum.TRANSFUSION.code());// 出库原因设为输血
        outStorgeEntity.setBloodBankDeliveryId(outStorageId);// 设置出库单据号
        outStorgeEntity.setOutStorgeTime(bloodSend.getRecipientTime());
        bloodOutStorgeService.save(outStorgeEntity);
        // 5.在收费表里面再塞一份
        BloodChargeEntity bloodChargeEntity = new BloodChargeEntity();
        bloodChargeEntity.setApplyDepartment(bloodSend.getDepartment());
        BeanUtils.copyProperties(bloodSend,bloodChargeEntity);
        // 5.1设置好价格内容
        BloodInformationEntity bloodInformationEntity = list.get(0);
        String cost = String.valueOf(bloodInformationEntity.getBloodPrice());
        bloodChargeEntity.setUnitPrice(cost);
        bloodChargeEntity.setQuantity("1");
        bloodChargeEntity.setTotalPrice(cost);
        bloodChargeEntity.setChargeState(BloodChargeEnum.CHARGE_UNVERIFIED.code()); // 未审核
        bloodChargeEntity.setChargeType(BloodChargeTypeEnum.BLOOD_COST.code()); // 血费
        bloodChargeEntity.setPayment(PaymentProjectEnum.BLOOD_COST.code());
        bloodChargeService.save(bloodChargeEntity);
        return 0;
    }

    @Override
    public BloodSendWithPatientVo selectBloodSendInfoByPatientId(BloodSendVo bloodSend) {
        return bloodSendDao.selectBloodSendInfoByPatientId(bloodSend);
    }

}
